﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Swift;
using SCM;
using UnityEngine.AI;
using System.Linq;
using Swift.Math;
using System;

public class UnitCreator : MonoBehaviour
{
    public EffectCreator EC;

    // 表示视野范围
    public GameObject VisionRange;

    // 表示阴影
    public GameObject ShadowPlane;

    // 表示寻路障碍
    public GameObject NavMeshSource;

    // 表示攻击范围
    public GameObject AttackRange;

    // 选中光效
    public GameObject SelRing;

    // 地表
    public MapGround MG;

    // 所有已经创建的单位模型
    StableDictionary<string, MapUnit> units = new StableDictionary<string, MapUnit>();

    // 创建一个指定类型的模型
    public MapUnit CreateModel(Unit u)
    {
        var isNeutral = u.Player == 0;
        var isMine = u.Player == GameCore.Instance.MePlayer;
        var withVision = u.cfg.VisionRadius > 0 && (isMine || isNeutral);
        var withNavObstacle = u.cfg.IsBuilding;
        var withShadow = !u.cfg.NoBody;
        return CreateModel(u.UnitType, u.UID, (float)u.cfg.AttackRange, withShadow, withVision, withNavObstacle);
    }

    public MapUnit CreateModel(string type, string uid, float attackRange, bool withShadow, bool withVision, bool withNavObstacle)
    {
        GameObject go = null;
        var model = transform.Find(type).gameObject;
        go = Instantiate(model) as GameObject;

        var vision = Instantiate(VisionRange) as GameObject;
        vision.name = "Vision";
        vision.transform.SetParent(go.transform);
        vision.transform.localPosition = Vector3.zero;
        vision.transform.localRotation = Quaternion.identity;
        vision.SetActive(withVision);

        if (withShadow)
        {
            var shadow = Instantiate(ShadowPlane) as GameObject;
            shadow.name = "Shadow";
            shadow.transform.SetParent(go.transform);
            shadow.transform.localPosition = Vector3.zero;
            shadow.transform.localScale = Vector3.one * 1.2f;
            shadow.transform.rotation = Quaternion.identity;
            shadow.SetActive(true);
        }

        if (withNavObstacle)
        {
            var obstacle = Instantiate(NavMeshSource) as GameObject;
            obstacle.name = "NavObstacle";
            obstacle.transform.SetParent(go.transform);
            obstacle.transform.localPosition = Vector3.zero;
            obstacle.transform.localRotation = Quaternion.identity;
            obstacle.SetActive(true);
        }

        var selRing = Instantiate(SelRing) as GameObject;
        selRing.name = "SelRing";
        selRing.transform.SetParent(go.transform);
        selRing.transform.localScale = Vector3.one;
        selRing.transform.localPosition = Vector3.zero;
        selRing.transform.localRotation = Quaternion.identity;
        selRing.SetActive(false);

        var ani = go.GetComponent<AnimationPlayer>();
        if (ani != null)
            ani.UC = this;

        var mu = go.GetComponent<MapUnit>();
        mu.WithVision = withVision;
        units[uid] = mu;
        return mu;
    }

    public MapUnit[] AllModels()
    {
        return units.Values.ToArray();
    }

    // 获取一个指定 UID 的模型
    public MapUnit GetModel(string uid)
    {
        return units.ContainsKey(uid) ? units[uid] : null;
    }

    // 解除 UnitCreator 对一个模型的托管，由外面自己管理
    public MapUnit UnhandleModel(string uid)
    {
        var mu = units[uid];
        units.Remove(uid);
        return mu;
    }

    // 移除一个模型
    public void RemoveModel(string uid, float destroyDelay = 0)
    {
        var mu = UnhandleModel(uid);

        if (destroyDelay <= 0)
            DestroyModel(mu);
        else
            StartCoroutine(DelayDestroyModel(mu, destroyDelay));
    }

    IEnumerator DelayDestroyModel(MapUnit mu, float delay)
    {
        yield return new WaitForSeconds(delay);
        DestroyModel(mu);
    }

    // 彻底销毁一个模型
    void DestroyModel(MapUnit mu)
    {
        var lst = new List<Transform>();

        if (mu.Attack01Stub != null && mu.Attack01Stub.childCount > 0)
            FC.For(mu.Attack01Stub.childCount, (i) => { lst.Add(mu.Attack01Stub.GetChild(i)); });

        if (mu.Attack02Stub != null && mu.Attack02Stub.childCount > 0)
            FC.For(mu.Attack02Stub.childCount, (i) => { lst.Add(mu.Attack02Stub.GetChild(i)); });

        foreach (var c in lst)
        {
            var ae = c.GetComponent<AttackEffect>();
            if (ae != null)
                EC.DestroyEffect(ae);
        }

        mu.MG = null;
        mu.transform.SetParent(null);
        mu.gameObject.SetActive(false);
        Destroy(mu.gameObject);
    }

    // 销毁所有模型
    public void DestroyAll()
    {
        foreach (var u in units.Values)
            Destroy(u.gameObject);

        units.Clear();
    }
}
